package photonpay

import (
	"crypto"
	"crypto/md5"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"fmt"

	"gitee.com/wangshh_123/cross-pay-go/src/config"
)

// GenerateSign 对请求体进行MD5withRSA签名，返回Base64编码签名字符串
// 参数:
//   - body: 需要签名的请求体
//
// 返回:
//   - string: Base64编码的签名字符串
//   - error: 签名过程中的错误
func GenerateSign(body interface{}) (string, error) {
	// 1. 参数校验
	if body == nil {
		return "", fmt.Errorf("请求体不能为空")
	}

	// 2. 序列化请求体
	bodyBytes, err := json.Marshal(body)
	if err != nil {
		return "", fmt.Errorf("序列化请求体失败: %v", err)
	}

	// 3. 检查序列化后的数据
	if len(bodyBytes) == 0 || string(bodyBytes) == "null" {
		return "", fmt.Errorf("序列化后的请求体为空")
	}

	// 4. 计算MD5哈希
	hash := md5.Sum(bodyBytes)

	// 5. 解析私钥
	privPem := []byte(config.GetConfig().PhotonPay.MerchantPrivateKey)
	block, _ := pem.Decode(privPem)
	if block == nil {
		return "", fmt.Errorf("无效的私钥PEM格式")
	}

	// 6. 解析PKCS8格式的私钥
	privKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return "", fmt.Errorf("解析PKCS8私钥失败: %v", err)
	}

	// 7. 类型断言为RSA私钥
	rsaPrivKey, ok := privKey.(*rsa.PrivateKey)
	if !ok {
		return "", fmt.Errorf("非RSA私钥")
	}

	// 8. 使用RSA私钥对MD5哈希进行签名
	signature, err := rsa.SignPKCS1v15(rand.Reader, rsaPrivKey, crypto.MD5, hash[:])
	if err != nil {
		return "", fmt.Errorf("RSA签名失败: %v", err)
	}

	// 9. Base64编码签名结果
	return base64.StdEncoding.EncodeToString(signature), nil
}

// VerifySign 验证MD5withRSA签名
// 参数:
//   - body: 需要验证的请求体
//   - signatureBase64: Base64编码的签名字符串
//
// 返回:
//   - bool: 签名是否有效
//   - error: 验证过程中的错误
func VerifySign(body interface{}, signatureBase64 string) (bool, error) {
	// 1. 参数校验
	if body == nil {
		return false, fmt.Errorf("请求体不能为空")
	}
	if signatureBase64 == "" {
		return false, fmt.Errorf("签名字符串不能为空")
	}

	// 2. 序列化请求体
	bodyBytes, err := json.Marshal(body)
	if err != nil {
		return false, fmt.Errorf("序列化请求体失败: %v", err)
	}

	// 3. 计算MD5哈希
	hash := md5.Sum(bodyBytes)

	// 4. 解析公钥
	pubPem := []byte(config.GetConfig().PhotonPay.PlatformPublicKey)
	block, _ := pem.Decode(pubPem)
	if block == nil {
		return false, fmt.Errorf("无效的公钥PEM格式")
	}

	// 5. 解析PKIX格式的公钥
	pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return false, fmt.Errorf("解析PKIX公钥失败: %v", err)
	}

	// 6. 类型断言为RSA公钥
	rsaPubKey, ok := pubKey.(*rsa.PublicKey)
	if !ok {
		return false, fmt.Errorf("非RSA公钥")
	}

	// 7. Base64解码签名
	signature, err := base64.StdEncoding.DecodeString(signatureBase64)
	if err != nil {
		return false, fmt.Errorf("Base64解码签名失败: %v", err)
	}

	// 8. 验证签名
	err = rsa.VerifyPKCS1v15(rsaPubKey, crypto.MD5, hash[:], signature)
	if err != nil {
		return false, fmt.Errorf("签名验证失败: %v", err)
	}

	return true, nil
}
